package controle;

import java.util.ArrayList;

import interfaces.PainelFase;

import componentes.Alvo;
import componentes.Aviao;

/**
 * 
 * Classe FaseThread.java que representa a thread que controlará os elementos da
 * fases
 * 
 * @desc Projeto BombarJ
 * @author Simone Carneiro Streitenberger 11888 CCO2003
 * @author Thiago Nascimento Comicio 11889 CCO2003
 * @professor Edison de Jesus
 * @disciplina Computação Gráfica 2 - CCO812
 * 
 */
public class FaseThread extends Thread {

	// aviao que sera controlado pela thread
	private Aviao aviao;

	// painel que conterá os objetos a serem impressos
	private PainelFase painel;

	// indica a pausa do jogo
	private boolean pause;

	// indica o deslocamento do avião
	private double deslocamento;

	// indica se a thread deverá ser terminada
	private int destrua;

	// lista de alvos a serem controlados
	private ArrayList<Alvo> alvos;

	// tamanho da onda na trajetória do avião
	private double tamOnda;

	// velocidade de deslocamento do alvo
	private int velocidadeAlvo;

	/**
	 * 
	 * Construtor da classe FaseThread.java
	 * 
	 * @param aviao
	 * @param painel
	 * @param deslocamento
	 * @param alvos
	 * @param tamOnda
	 * @param velocidadeAlvo
	 */
	public FaseThread(Aviao aviao, PainelFase painel, double deslocamento,
			ArrayList<Alvo> alvos, double tamOnda, int velocidadeAlvo) {
		// recebe os valores e os atribui aos atributos
		this.aviao = aviao;
		this.painel = painel;
		this.deslocamento = deslocamento;
		this.alvos = alvos;
		this.tamOnda = tamOnda;
		this.velocidadeAlvo = velocidadeAlvo;

		// indica o fim da Thread
		destrua = 0;
		this.pause = false;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Thread#run()
	 */
	public void run() {
		double j, i = 0, t = 0;
		int y, x;

		// loop que acontece até que a variável destrua seja setada para 1
		for (;;) {
			// se não estiver pausado, executa as ações
			if (!pause) {

				// movimentação avião
				j = Math.sin(i - t);
				y = (int) Math.round(j * 45.0);
				x = (int) Math.round(i * tamOnda);

				aviao.setPosicao(x, y);

				// movimentação alvos
				for (Alvo alvo : alvos) {
					if (alvo.isDescida()) {
						if (alvo.getTamanho() > 0) {
							alvo.setTamanho(alvo.getTamanho() - velocidadeAlvo);
						} else {
							alvo.setTamanho(alvo.getTamanho() + velocidadeAlvo);
							alvo.setDescida(false);
						}
					} else {
						if (alvo.getTamanho() < alvo.getTamanhoInicial()) {
							alvo.setTamanho(alvo.getTamanho() + velocidadeAlvo);
						} else {
							alvo.setTamanho(alvo.getTamanho() - velocidadeAlvo);
							alvo.setDescida(true);
						}
					}
				}

				// repinta o painel
				painel.repaint();

				// interrompe por 15 milisegundos
				try {
					Thread.sleep(15);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}

				// desloca o valor de x do avião
				i += deslocamento;
				if (x >= (painel.getWidth() + 150)) {
					i = 0;
					t = 1.5 * Math.PI * Math.random();
				}
			}

			// verifica se a thread deve ser destruída
			if (destrua == 1) {
				break;
			}
		}
	}

	/**
	 * 
	 * Método que retorna o valor do atributo aviao.
	 * 
	 * @return O atributo aviao.
	 * 
	 */
	public Aviao getAviao() {
		return aviao;
	}

	/**
	 * 
	 * Método que seta o atributo aviao para um novo valor.
	 * 
	 * @param aviao
	 *            O atributo aviao � setado.
	 * 
	 */
	public void setAviao(Aviao aviao) {
		this.aviao = aviao;
	}

	/**
	 * 
	 * Método que retorna o valor do atributo painel.
	 * 
	 * @return O atributo painel.
	 * 
	 */
	public PainelFase getPainel() {
		return painel;
	}

	/**
	 * 
	 * Método que seta o atributo painel para um novo valor.
	 * 
	 * @param painel
	 *            O atributo painel � setado.
	 * 
	 */
	public void setPainel(PainelFase painel) {
		this.painel = painel;
	}

	/**
	 * 
	 * Método que retorna o valor do atributo pause.
	 * 
	 * @return O atributo pause.
	 * 
	 */
	public boolean isPause() {
		return pause;
	}

	/**
	 * 
	 * Método que seta o atributo pause para um novo valor.
	 * 
	 * @param pause
	 *            O atributo pause � setado.
	 * 
	 */
	public void setPause(boolean pause) {
		this.pause = pause;
	}

	/**
	 * 
	 * Método que retorna o valor do atributo deslocamento.
	 * 
	 * @return O atributo deslocamento.
	 * 
	 */
	public double getDeslocamento() {
		return deslocamento;
	}

	/**
	 * 
	 * Método que seta o atributo deslocamento para um novo valor.
	 * 
	 * @param deslocamento
	 *            O atributo deslocamento � setado.
	 * 
	 */
	public void setDeslocamento(double deslocamento) {
		this.deslocamento = deslocamento;
	}

	/**
	 * 
	 * Método que tem por função indicar que a thread deve ser terminada
	 * 
	 */
	public void destrua() {
		this.destrua = 1;
	}
}
